﻿#include <QtConcurrent/QtConcurrent>

#include "zmqresponder.h"
#include "WaitUtils.h"
#include "widgettcpcfg.h"
#define CHAR_MAX_LENGTH        1024

ZmqResponder::ZmqResponder(QObject *parent) : BaseResponder(parent)
{
    _mutex=new QMutex();
    _waitCondition=new QWaitCondition();
}

bool ZmqResponder::connectToHost()
{
    QString address=getCommParam();
    _context=zmq_ctx_new();
    //reply
    _socket=zmq_socket(_context,ZMQ_REP);
    int rc=zmq_bind(_socket,address.toUtf8());
    qDebug()<<__FUNCTION__<<__LINE__<<address.toUtf8()<<rc;
    if(rc!=0)
    {
        return false;
    }

    int timeout=3000;
    if(zmq_setsockopt(_socket, ZMQ_RCVTIMEO, &timeout, sizeof(int)) < 0)
    {
        qDebug()<<"Failed to setsocketopt ZMQ_RCVTIMEO error";
    }
    _isRunning=true;
    QtConcurrent::run([this]()
    {
        int maxLen=1024*10;
        char *receivetMsg = new char[maxLen];
        while(_isRunning)
        {
            QThread::msleep(200);
            int len = zmq_recv(_socket, receivetMsg, maxLen,0);
            if(len>0)
            {
                _sendArr.clear();
                QByteArray data(receivetMsg,len);
                emit onRequest(data);
                QMutexLocker locker(_mutex);
                if(_waitCondition->wait(_mutex,3000)&&!_sendArr.isEmpty())
                {
                    zmq_send(_socket,_sendArr.data(),len,0);
                }
                else
                {
                    char reply[60] = "receive data ok but response timeout";
                    zmq_send(_socket,reply,sizeof(reply),0);
                }
            }
        }
        delete[] receivetMsg;
    });
    return true;
}

bool ZmqResponder::isConnected()
{
    return true;
}

bool ZmqResponder::disConnect()
{
    _isRunning=false;
    zmq_close(_socket);
    zmq_ctx_destroy(_context);
    return true;
}


void ZmqResponder::response(QByteArray data)
{
    QMutexLocker locker(_mutex); // 使用 QMutexLocker 自动管理锁
    _sendArr.append(data);
    _waitCondition->wakeOne();
}

QWidget *ZmqResponder::getConfigWidget()
{
    WidgetTcpCfg *cfg=new WidgetTcpCfg();
    cfg->setComm(this);
    return cfg;
}
